package cryptography.symmetric.AES;

import java.security.*;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.*;

public class AESCrytographyWithSalt {

	private static final String ALGORITHM = "AES";
	private static final int ITERATIONS = 2;
	private static final byte[] keyValue = new byte[] { 'T', 'h', 'i', 's',
			'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };

	//Hàm mã hóa
	public static String encrypt(String value, String salt) throws Exception {
		Key key = generateKey();
		Cipher c = Cipher.getInstance(ALGORITHM);
		c.init(Cipher.ENCRYPT_MODE, key);

		String valueToEnc = null;
		String eValue = value;
		for (int i = 0; i < ITERATIONS; i++) {
			valueToEnc = salt + eValue;
			byte[] encValue = c.doFinal(valueToEnc.getBytes());
			eValue = new BASE64Encoder().encode(encValue);
		}
		return eValue;
	}
	
	//Hàm giải mã
	public static String decrypt(String value, String salt) throws Exception {
		Key key = generateKey();
		Cipher c = Cipher.getInstance(ALGORITHM);
		c.init(Cipher.DECRYPT_MODE, key);

		String dValue = null;
		String valueToDecrypt = value;
		for (int i = 0; i < ITERATIONS; i++) {
			byte[] decordedValue = new BASE64Decoder()
					.decodeBuffer(valueToDecrypt);
			byte[] decValue = c.doFinal(decordedValue);
			dValue = new String(decValue).substring(salt.length());
			valueToDecrypt = dValue;
		}
		return dValue;
	}

	private static Key generateKey() throws Exception {
		Key key = new SecretKeySpec(keyValue, ALGORITHM);
		// SecretKeyFactory keyFactory =
		// SecretKeyFactory.getInstance(ALGORITHM);
		// key = keyFactory.generateSecret(new DESKeySpec(keyValue));
		return key;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			String password = "mypassword";
			String salt = "this is a simple clear salt";
			String passwordEnc;

			passwordEnc = encrypt(password, salt);
			String passwordDec = decrypt(passwordEnc, salt);

			System.out.println("Salt Text : " + salt);
			System.out.println("Plain Text : " + password);
			System.out.println("Encrypted : " + passwordEnc);
			System.out.println("Decrypted : " + passwordDec);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
